%% nth0/3
%% size/2
%% get_element_index/3
%% get_nth_element/3

:- dynamic nth0/3,
	nth1/3,
	size/2,
	get_element_index/3,
	get_nth_element/3.
	
:- export nth0/3,
	nth1/3,
	size/2,
	get_element_index/3,
	get_nth_element/3.

%%nth( X, List, Item ) :-
%    nth1( X, List, Elem ), !.

%   nth0(+N, +List, ?Elem) is true when Elem is the Nth member of List,
%   counting the first as element 0.  (That is, throw away the first
%   N elements and unify Elem with the next.)  It can only be used to
%   select a particular element given the list and index.  For that
%   task it is more efficient than nmember.
%   nth1(+N, +List, ?Elem) is the same as nth0, except that it counts from
%   1, that is nth(1, [H|_], H).

nth0(0, [Head|_], Head) :- !.
nth0(N, [_|Tail], Elem) :-
    nonvar(N),
    M is N-1,
    nth0(M, Tail, Elem).
nth0(N,[_|T],Item) :-       % Clause added KJ 4-5-87 to allow mode
    var(N),         % nth0(-,+,+)
    nth0(M,T,Item),
    N is M + 1.
   
nth1(1,[X|_],X) :- !.
nth1(Idx,[_|List],X) :-
    Idx > 1,
    Idx1 is Idx-1,
    nth1(Idx1,List,X).
     
%	length of a list    
size([],0).
size([_|T],N):-
    size(T,M),
    N is M+1.


%% get_element_index(2,[1,5,6,2,4,3],N).
%% N = 4.
get_element_index(Element, List, Index) :-
	get_element_index(Element, List, 1, Index).
get_element_index(Element, [Head|Tail], N, Index) :-
	(
	Element = Head -> 
		Index is N
	;
		N1 is N+1,
		get_element_index(Element, Tail, N1, Index)
	).	

%% get_nth_element(['X1','X5','X6','X2','X4','X3'],3,Item).
get_nth_element([],_,_) :-
        write('There is no such element in the list'),nl.
get_nth_element([Element|_],1,Item) :- 	%% index starts with 1
        % write(['The element is ',Element]),
        Item = Element, nl.
get_nth_element([_|List],N,Item) :-
        N1 is N-1,
        get_nth_element(List,N1,Item).
